package com.mycitybikes.android.view;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.util.Log;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.mycitybikes.android.Constants;
import com.mycitybikes.android.model.StationLocation;
public class MapLocationItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private static final int CURRENT_POSITION_OVERLAY_INDEX = 0;
private MapView mapView;
private List<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private Drawable meMarker;
private Drawable highlightMarker;
private GeoPoint currentPosition;
private List<StationLocation> stationLocations;
private int selectedOverlayIndex;
private Toast lastText;
public MapLocationItemizedOverlay(MapView mapView, Drawable meMarker,
Drawable stationMarker, Drawable highlightMarker,
GeoPoint currentPosition, List<StationLocation> bikeLocations) {
super(boundCenterBottom(stationMarker));
this.mapView = mapView;
this.meMarker = meMarker;
// this.stationMarker = boundCenterBottom(stationMarker);
this.highlightMarker = boundCenterBottom(highlightMarker);
this.currentPosition = currentPosition;
this.stationLocations = bikeLocations;
populate();
}
@Override
protected OverlayItem createItem(int i) {
OverlayItem item;
if (i == CURRENT_POSITION_OVERLAY_INDEX) {
item = new OverlayItem(currentPosition, "", "");
item.setMarker(boundCenterBottom(meMarker));
} else {
final StationLocation l = this.stationLocations.get(i - 1);
item = new OverlayItem(l.getLocation(), "", "");
}
mOverlays.add(item);
return item;
}
@Override
public int size() {
return 1 + stationLocations.size();
}
@Override
protected boolean onTap(int index) {
actUponTapLocation(index, "");
return super.onTap(index);
}
public void actUponTapLocation(int overlayIndex, String prefixMessage) {
// not sure if this is working well.
final OverlayItem overlayItem = mOverlays.get(overlayIndex);
Log.d(Constants.TAG, "tapping index " + overlayIndex + " "
+ overlayItem);
mapView.getController().animateTo(overlayItem.getPoint());
String text;
if (overlayIndex == CURRENT_POSITION_OVERLAY_INDEX) {
text = "Your current position.\n"
+ getFirstReversedGeocodedAddress(currentPosition);
Log.v(Constants.TAG, "onTapText:" + text);
} else {
StationLocation stationLocation = stationLocations
.get(overlayIndex - 1);
text = prefixMessage + stationLocation.getStationInfo();
Log.v(Constants.TAG, "tapped station: " + stationLocation + "onTapText: "
+ text);
}
highlightSelectedOverlayItem(overlayIndex, overlayItem);
if (lastText == null) {
lastText = Toast.makeText(mapView.getContext(), text,
Toast.LENGTH_LONG);
} else {
lastText.setText(text);
}
lastText.show();
}
private void highlightSelectedOverlayItem(final int overlayIndex,
final OverlayItem overlayItem) {
if (selectedOverlayIndex != CURRENT_POSITION_OVERLAY_INDEX) {
mOverlays.get(selectedOverlayIndex).setMarker(null);
}
if (overlayIndex != CURRENT_POSITION_OVERLAY_INDEX) {
overlayItem.setMarker(highlightMarker);
}
Log.v(Constants.TAG, "highlighted. view should be redrawn");
selectedOverlayIndex = overlayIndex;
}
private String getFirstReversedGeocodedAddress(GeoPoint position) {
Geocoder geoCoder = new Geocoder(mapView.getContext(), Locale
.getDefault());
String address = "";
try {
List<Address> addresses = geoCoder.getFromLocation(position
.getLatitudeE6() / 1E6, position.getLongitudeE6() / 1E6, 1);
if (addresses.size() > 0) {
for (int i = 0; i < addresses.get(0).getMaxAddressLineIndex(); i++)
address += addresses.get(0).getAddressLine(i) + "\n";
}
} catch (Exception e) {
Log.e(Constants.TAG,
"Unable to reverse geocode address for position "
+ position + ". " + e.getMessage(), e);
}
return address;
}
// FIXME we shouldn't have to expose this
public int findOverlayIndex(int stationIndex) {
for (int i = 0; i < stationLocations.size(); i++) {
StationLocation stationLocation = stationLocations.get(i);
if (stationLocation.getId() == stationIndex) {
return i + 1;
}
}
throw new IllegalArgumentException("station with index " + stationIndex
+ " doesn't exists as overlay item");
}
}